package com.hs.myshell.edit;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.nio.CharBuffer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

import com.hs.myshell.ssh.ISSHClient;
import com.hs.myshell.ssh.SSHClient;

import net.schmizz.sshj.common.IOUtils;

public class TerminalEditor extends EditorPart {
	
	private ISSHClient sshClient;

	public static String ID = "com.hs.myshell.edit.terminaleditor";
	
	/**
	 * ��Ļ
	 */
	private Text screen;
	/**
	 * ����������
	 */
	private Text commandInput;
	private InputStream originInputStream;
	private OutputStream originOutputStream;
	private PipedInputStream inputStream;
	private InputStreamReader reader;
	private volatile Job readerJob;
	
	public TerminalEditor() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		// TODO Auto-generated method stub
		this.setSite(site);
		this.setInput(input);
	}

	@Override
	public boolean isDirty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		Composite top = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		top.setLayout(layout);
		
		screen = new Text(top, SWT.BORDER|SWT.MULTI|SWT.WRAP);
		screen.setLayoutData(new GridData(GridData.FILL,GridData.FILL,true,true));
		screen.setEditable(false);
		screen.setBackground(screen.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
		screen.setForeground(screen.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
		
		commandInput = new Text(top, SWT.BORDER|SWT.WRAP);
		GridData commandLayoutData = new GridData(GridData.FILL,GridData.FILL,true,false);
		commandLayoutData.heightHint = commandInput.getLineHeight() * 2;
		commandInput.setLayoutData(commandLayoutData);
		TerminalEditor editor = this;
		commandInput.addKeyListener(new KeyListener() {
			
			@Override
			public void keyReleased(KeyEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.character == SWT.CR) {
					sendCommand();
					e.doit = false;
				}
			}

			private void sendCommand() {
				try {
//					String command = commandInput.getText();
					
					System.out.println();
					String cc = commandInput.getText();
					char[] charArray = cc.toCharArray();
					for (char c : charArray) {
						System.out.println(c);
					}
					String command = cc+"\r\n";
					try {
			            getOriginOutputStream().write(command.getBytes("UTF-8"));
			            getOriginOutputStream().flush();
			        } catch (SocketException var4) {
//			            this.displayTextInTerminal(var4.getMessage());
//			            String strMsg = TerminalMessages.SocketError + "!\n" + var4.getMessage();
//			            this.showErrorMessage(strMsg);
//			            this.disconnectTerminal();
			        } catch (IOException var5) {
//			            this.disconnectTerminal();
			        }
//					sshClient.sendCmd(command,editor);
					commandInput.setText("");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		
		//read OutPutStream
//		Runnable runnable = new Runnable() {
//			
//			@Override
//			public void run() {
//				while (true) {
//					byte[] b = new byte[128];
//					try {
//						while (inputStream != null && inputStream.read(b) != -1) {
//							System.out.println(new String(b,"UTF-8"));
//						}
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//				}
//				
//			}
//		};
//		new Thread(runnable).start();
		
//		new Thread(new Runnable() {
//			
//			@Override
//			public void run() {
//				byte[] bytes = new byte[2048];
//				System.out.println("pulling out");
//		        int n;
//		        try {
//					while((n = originInputStream.read(bytes)) != -1) {
////		            this.fControl.getRemoteToTerminalOutputStream().write(bytes, 0, n);
//						String outPut = new String(bytes);
////						System.out.println(outPut);
//						appendOutPut(outPut);
//					}
//				} catch (IOException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//				
//			}
//		}).start();
	}
	
	public void showMsg() {
		if (this.readerJob == null) {
            this.readerJob = new Job("Terminal data reader") {
                protected IStatus run(IProgressMonitor monitor) {
                    IStatus var2 = Status.OK_STATUS;

                    Object status;
                    try {
                        while(true) {
                        	byte[] bytes = new byte[2048];
            				System.out.println("pulling out");
            		        int n;
                        	System.out.println("available... ...");
                        	try {
								while((n = originInputStream.read(bytes)) != -1) {
//            		            this.fControl.getRemoteToTerminalOutputStream().write(bytes, 0, n);
										String outPut = new String(bytes);
										System.out.println(outPut);
										Display.getDefault().syncExec(new Runnable() {
										    public void run() {
										    	appendOutPut(outPut);
										    }
										}); 
										bytes = new byte[2048];
								}
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}

                            if (monitor.isCanceled()) {
                                status = Status.CANCEL_STATUS;
                                break;
                            }

//                            try {
//                            	TerminalEditor.this.processText();
//                            } catch (Exception e) {
//                            	sshClient.logout();
//                                status = new Status(4, "org.eclipse.tm.terminal.control", e.getLocalizedMessage(), e);
//                                break;
//                            }
                        }
                    } finally {
                        synchronized(TerminalEditor.this) {
                            if (TerminalEditor.this.readerJob == this) {
                            	TerminalEditor.this.readerJob = null;
                            }

                        }
                    }

                    return (IStatus)status;
                }
            };
            this.readerJob.setSystem(true);
            this.readerJob.schedule();
        }
	}

	public void startReaderJob() {
		this.inputStream = new PipedInputStream(8192);
		try {
			this.reader = new InputStreamReader(this.inputStream,"UTF-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		
		
		if (this.readerJob == null) {
            this.readerJob = new Job("Terminal data reader") {
                protected IStatus run(IProgressMonitor monitor) {
                    IStatus var2 = Status.OK_STATUS;

                    Object status;
                    try {
                        while(true) {
                        	System.out.println("available... ...");
                            while(inputStream.available() == 0 && !monitor.isCanceled()) {
                                try {
                                	TerminalEditor.this.inputStream.waitForAvailable(500L);
                                } catch (InterruptedException var12) {
                                    Thread.currentThread().interrupt();
                                }
                            }

                            if (monitor.isCanceled()) {
                                status = Status.CANCEL_STATUS;
                                break;
                            }

                            try {
                            	TerminalEditor.this.processText();
                            } catch (Exception e) {
                            	sshClient.logout();
                                status = new Status(4, "org.eclipse.tm.terminal.control", e.getLocalizedMessage(), e);
                                break;
                            }
                        }
                    } finally {
                        synchronized(TerminalEditor.this) {
                            if (TerminalEditor.this.readerJob == this) {
                            	TerminalEditor.this.readerJob = null;
                            }

                        }
                    }

                    return (IStatus)status;
                }
            };
            this.readerJob.setSystem(true);
            this.readerJob.schedule();
        }
	}
	
	
	private int fNextChar = -1;
	private boolean hasNextChar() throws IOException {
        return this.fNextChar >= 0 ? true : this.reader.ready();
    }
	protected void processText() {
		try {
			while(hasNextChar()) {
				System.out.println("processText..........");
//				CharBuffer charArr = CharBuffer.allocate(1024);
//				reader.read(charArr);
//				System.out.println(charArr.toString());
				ByteArrayOutputStream readFully = IOUtils.readFully(inputStream);
				String string = readFully.toString();
				System.out.println(string);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public void setFocus() {
		String text = commandInput.getText();
		System.out.println(text);
		commandInput.setText("");

	}
	
	public void appendOutPut(String str) {
		this.screen.append(str);
	}

	public void setISSHClient(ISSHClient sshClient) {
		this.sshClient = sshClient;
	}

	public InputStream getOriginInputStream() {
		return originInputStream;
	}

	public void setOriginInputStream(InputStream inputStream) {
		this.originInputStream = inputStream;
	}

	public OutputStream getOriginOutputStream() {
		return originOutputStream;
	}

	public void setOriginOutputStream(OutputStream originOutputStream) {
		this.originOutputStream = originOutputStream;
	}
}
